package org.daochong.lang;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.daochong.lang.uai.UniteAccessInterfaceFactory;

public class Service<T> implements IService<T> {

	private IDao<T> dao;
	private JdbcTemplate jdbcTemplate;
	private DataSource dataSource;
	protected Class<T> clazz;
	private UniteAccessInterfaceFactory uaiFactory;

	@SuppressWarnings("unchecked")
	public Service() {
		Type genType = this.getClass().getGenericSuperclass();
		Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
		this.clazz = (Class<T>) params[0];
	}

	public UniteAccessInterfaceFactory getUaiFactory() {
		return uaiFactory;
	}

	public void setUaiFactory(UniteAccessInterfaceFactory uaiFactory) {
		this.uaiFactory = uaiFactory;
	}

	public Service(Class<T> clazz) {
		this.clazz = clazz;
	}

	public IDao<T> getDao() {
		if (this.dao == null) {
			Dao<T> dao = new Dao<T>(clazz);
			dao.setDataSource(getDataSource());
			dao.setJdbcTemplate(getJdbcTemplate());
			dao.setUaiFactory(getUaiFactory());
			this.dao = dao;
		}
		return this.dao;
	}

	public void setDao(IDao<T> dao) {
		this.dao = dao;
	}

	public T load(T obj) throws SQLException {
		return getDao().load(obj);
	}

	public T load(Object... keys) throws SQLException {
		return getDao().load(keys);
	}

	public boolean create(T obj) throws SQLException {
		return getDao().create(obj);
	}

	public boolean save(T obj) throws SQLException {
		return getDao().save(obj);
	}

	public boolean updateWithoutNull(T obj) throws SQLException {
		return getDao().updateWithoutNull(obj);
	}

	public boolean updatePart(Map<String, Object> data, String... keys) throws SQLException {
		return getDao().updatePart(data, keys);
	}

	public boolean exists(T obj) throws SQLException {
		return getDao().exists(obj);
	}

	public boolean exists(Object... keys) throws SQLException {
		return getDao().exists(keys);
	}

	public boolean delete(T obj) throws SQLException {
		return getDao().delete(obj);
	}

	public boolean delete(Object... keys) throws SQLException {
		return getDao().delete(keys);
	}

	public List<T> list() throws SQLException {
		return getDao().list();
	}

	public List<T> list(Map<String, Object> parms) throws SQLException {
		return getDao().list(parms);
	}

	public PageResult<T> list(Page page) throws SQLException {
		return getDao().list(page);
	}

	public PageResult<T> list(Page page, String sql) throws SQLException {
		return getDao().list(page, sql);
	}

	public PageResult<T> list(Page page, String sql, List<Object> params) throws SQLException {
		return getDao().list(page, sql, params);
	}

	public PageResult<T> list(Page page, String sql, Map<String, Object> params) throws SQLException {
		return getDao().list(page, sql, params);
	}

	public PageResult<T> list(Page page, Map<String, Object> params) throws SQLException {
		return getDao().list(page, params);
	}

	public PageResult<T> list(Page page, Map<String, Object> params, Map<String, String> orders) throws SQLException {
		return getDao().list(page, params, orders);
	}

	public JdbcTemplate getJdbcTemplate() {
		return jdbcTemplate;
	}

	public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
		this.jdbcTemplate = jdbcTemplate;
	}

	public DataSource getDataSource() {
		return dataSource;
	}

	public void setDataSource(DataSource dataSource) {
		this.dataSource = dataSource;
	}

	public JdbcTemplate requestJdbcTemplate() {
		if (this.getJdbcTemplate() != null) {
			return this.getJdbcTemplate();
		} else if (this.getDataSource() != null) {
			return new JdbcTemplate(getDataSource());
		} else if (this.getUaiFactory() != null) {
			return this.getUaiFactory().getTemplate(JdbcTemplate.class);
		} else {
			JdbcTemplate jdbc = JdbcTemplateFactory.getDefault().getJdbcTemplate();
			if (jdbc != null) {
				return jdbc;
			}
			throw new RuntimeException("JdbcTempate is Null");
		}
	}
}
